package com.flow.framework.base.system.listener.lifecycle;

import com.flow.framework.base.properties.FrameworkBaseConfigProperties;
import com.flow.framework.base.system.checker.impl.AllocationRemoteStatusChecker;
import com.flow.framework.base.system.checker.impl.DiscoveryRemoteStatusChecker;
import com.flow.framework.common.util.verify.VerifyUtil;
import com.flow.framework.core.constant.FrameworkCoreConstant;
import com.flow.framework.core.service.properties.ISystemConfigPropertiesService;
import com.flow.framework.core.system.initialization.ApplicationContextHelper;
import com.flow.framework.core.system.listener.lifecycle.ISystemLifecycleListener;
import com.flow.framework.core.system.thread.pool.executor.SystemStatusCheckerExecutor;
import lombok.RequiredArgsConstructor;
import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.core.env.Environment;

import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * 网络监控检查初始化类
 *
 * @author luoguopiao
 * @version 0.0.1
 * @date 2022/12/17
 */
@RequiredArgsConstructor
public class NetworkStatusListenerLifecycleListener implements ISystemLifecycleListener {

    protected final CompositeDiscoveryClient discoveryClient;

    protected final Environment environment;

    protected final FrameworkBaseConfigProperties frameworkBaseConfigProperties;

    protected final ISystemConfigPropertiesService systemConfigPropertiesService;

    /**
     * @inheritDoc
     */
    @Override
    public void onStartUp() {
        if (VerifyUtil.isTrue(frameworkBaseConfigProperties.getEnableDiscoveryRemoteStatusCheck())) {
            String appName = systemConfigPropertiesService.getConfigValue(FrameworkCoreConstant.SERVICE_NAME_KEY);
            Set<String> serviceNamesOrPlaceHolders = new HashSet<>();
            Collection<Object> feignClients = ApplicationContextHelper.getBeansWithAnnotation(FeignClient.class);
            feignClients.forEach(feignClient -> {
                if (!Proxy.isProxyClass(feignClient.getClass())) {
                    return;
                }
                Class<?>[] interfaces = feignClient.getClass().getInterfaces();
                for (Class<?> interfaceElement : interfaces) {
                    FeignClient annotation = interfaceElement.getDeclaredAnnotation(FeignClient.class);
                    if (null == annotation) {
                        return;
                    }
                    String serviceNamesOrPlaceHolder = annotation.name();
                    if (!VerifyUtil.isEmpty(serviceNamesOrPlaceHolder) && !serviceNamesOrPlaceHolder.equals(appName)) {
                        serviceNamesOrPlaceHolders.add(serviceNamesOrPlaceHolder);
                    }
                }
            });
            SystemStatusCheckerExecutor.schedule(
                    new DiscoveryRemoteStatusChecker(discoveryClient, environment, serviceNamesOrPlaceHolders)
            );
        }
        SystemStatusCheckerExecutor.schedule(new AllocationRemoteStatusChecker(frameworkBaseConfigProperties));
    }
}
